package com.wallet.trans.services.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.safeheron.client.webhook.*;
import com.wallet.trans.dao.ComMpcWebHookDao;
import com.wallet.trans.dao.SysRocketmqDedupDao;
import com.wallet.trans.domain.ProducerMqMessage;
import com.wallet.trans.domain.TransMqMessage;
import com.wallet.trans.entity.ComMpcWebHook;
import com.wallet.trans.entity.SysRocketmqDedup;
import com.wallet.trans.enums.MpcTransactionStatusEnum;
import com.wallet.trans.enums.ResultCodeEnum;
import com.wallet.trans.producer.TransMqProducer;
import com.wallet.trans.resp.SendToResp;
import com.wallet.trans.services.MpcService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.Objects;


@Slf4j
@Service("mpcService")
public class MpcServiceImpl implements MpcService {
    private WebhookConverter webhookConverter;

    @Autowired
    ComMpcWebHookDao comMpcWebHookDao;

    @Autowired
    private SysRocketmqDedupDao sysRocketmqDedupDao;

    @Autowired
    private TransMqProducer transMqProducer;

    @Value("${mpc.safeheron.api-public-key}")
    private String apiPublicKey;

    @Value("${mpc.safeheron.web-hook-private}")
    private String webHookPrivate;
    @Override
    public WebHookResponse webHookCallBack(String timestamp, String sig, String key, String bizContent) {
        WebHookResponse webHookResponse = new WebHookResponse();
        webHookResponse.setCode("201");
        webHookResponse.setMessage("FAIL");
        WebHook webHook = new WebHook();
        webHook.setTimestamp(timestamp);
        webHook.setSig(sig);
        webHook.setKey(key);
        webHook.setBizContent(bizContent);
        try {
            webhookConverter = new WebhookConverter(apiPublicKey, webHookPrivate);
            WebHookBizContent webHookBizContent = webhookConverter.convert(webHook);
            /**收到mpc推送消息记录*/
            if (webHookBizContent.getEventDetail() instanceof TransactionParam) {
                ComMpcWebHook comMpcWebHook = new ComMpcWebHook();
                comMpcWebHook.setTimestamp(timestamp);
                comMpcWebHook.setAesKey(key);
                comMpcWebHook.setSig(sig);
                comMpcWebHook.setBizContent(bizContent);

                TransactionParam transactionParam = (TransactionParam) webHookBizContent.getEventDetail();
                log.info("交易事件详情【{}】", transactionParam);
                comMpcWebHook.setEventDetail(JSONObject.toJSONString(transactionParam));
                comMpcWebHook.setEventType(webHookBizContent.getEventType());
                comMpcWebHook.setTxKey(transactionParam.getTxKey());
                comMpcWebHook.setCreateTime(System.currentTimeMillis());
                log.info("mpc推送记录【{}】", comMpcWebHook);
                comMpcWebHookDao.insert(comMpcWebHook);
                /**
                 * 交易取消、拒绝、失败时表示该mpc交易完成,发mq消息
                 * */
                if(transactionParam.getTransactionStatus().equals(MpcTransactionStatusEnum.CANCELLED.getName()) ||
                    transactionParam.getTransactionStatus().equals(MpcTransactionStatusEnum.FAILED.getName()) ||
                    transactionParam.getTransactionStatus().equals(MpcTransactionStatusEnum.REJECTED.getName())){
                    LambdaQueryWrapper<SysRocketmqDedup> queryWrapper = Wrappers.lambdaQuery();
                    queryWrapper.eq(SysRocketmqDedup::getTxKey, transactionParam.getTxKey());
                    SysRocketmqDedup sysRocketmqDedupTxkey = sysRocketmqDedupDao.selectOne(queryWrapper);
                    if (Objects.nonNull(sysRocketmqDedupTxkey)){

                        ProducerMqMessage producerMqMessage = new ProducerMqMessage();
                        SendToResp.ResData data = new SendToResp.ResData();
                        data.setHex(sysRocketmqDedupTxkey.getTxKey());
                        producerMqMessage.setData(data);
                        producerMqMessage.setMessage(JSON.parseObject(sysRocketmqDedupTxkey.getMsgBody(), TransMqMessage.class));
                        producerMqMessage.setCode(ResultCodeEnum.OPERATION_ERROR.getCode());
                        producerMqMessage.setMsg(ResultCodeEnum.OPERATION_ERROR.getMessage());
                        /**
                         * 插入mq推送记录
                         * */
                        SysRocketmqDedup sysRocketmqDedup = new SysRocketmqDedup();
                        sysRocketmqDedup.setMqGroup(sysRocketmqDedupTxkey.getMqGroup());
                        sysRocketmqDedup.setMqTopic(sysRocketmqDedupTxkey.getMqTopic());
                        sysRocketmqDedup.setSerialNo(sysRocketmqDedupTxkey.getSerialNo());
                        sysRocketmqDedup.setMsgId(sysRocketmqDedupTxkey.getMsgId());
                        sysRocketmqDedup.setMsgBody(sysRocketmqDedupTxkey.getMsgBody());
                        sysRocketmqDedup.setCreateTime(System.currentTimeMillis());
                        sysRocketmqDedup.setResp(JSONObject.toJSONString(producerMqMessage));
                        sysRocketmqDedup.setStatus(0);

                        sysRocketmqDedupDao.insert(sysRocketmqDedup);
                        log.info("插入记录【{}】", sysRocketmqDedup);
                        transMqProducer.send(producerMqMessage);

                        log.info("mq失败记录【{}】", producerMqMessage);
                    }
                    webHookResponse.setMessage("SUCCESS");
                    webHookResponse.setCode("200");
                    log.info("当前mpc交易key 【{}】", transactionParam.getTxKey());
                }

                /**
                 * 交易成功，发mq消息
                 * */
                if(transactionParam.getTransactionStatus().equals(MpcTransactionStatusEnum.COMPLETED.getName())){
                    LambdaQueryWrapper<SysRocketmqDedup> queryWrapper = Wrappers.lambdaQuery();
                    queryWrapper.eq(SysRocketmqDedup::getTxKey, transactionParam.getTxKey());
                    SysRocketmqDedup sysRocketmqDedupTxkey = sysRocketmqDedupDao.selectOne(queryWrapper);
                    if (Objects.nonNull(sysRocketmqDedupTxkey)){
                        ProducerMqMessage producerMqMessage = new ProducerMqMessage();
                        SendToResp.ResData data = new SendToResp.ResData();
                        data.setHex(sysRocketmqDedupTxkey.getTxKey());
                        data.setHash(transactionParam.getTxHash());
                        producerMqMessage.setData(data);

                        producerMqMessage.setMessage(JSON.parseObject(sysRocketmqDedupTxkey.getMsgBody(), TransMqMessage.class));
                        producerMqMessage.setCode(ResultCodeEnum.PASS.getCode());
                        producerMqMessage.setMsg(ResultCodeEnum.PASS.getMessage());

                        /**
                         * 插入mq推送记录
                         * */
                        SysRocketmqDedup sysRocketmqDedup = new SysRocketmqDedup();
                        sysRocketmqDedup.setMqGroup(sysRocketmqDedupTxkey.getMqGroup());
                        sysRocketmqDedup.setMqTopic(sysRocketmqDedupTxkey.getMqTopic());
                        sysRocketmqDedup.setSerialNo(sysRocketmqDedupTxkey.getSerialNo());
                        sysRocketmqDedup.setMsgId(sysRocketmqDedupTxkey.getMsgId());
                        sysRocketmqDedup.setMsgBody(sysRocketmqDedupTxkey.getMsgBody());
                        sysRocketmqDedup.setCreateTime(System.currentTimeMillis());
                        sysRocketmqDedup.setResp(JSONObject.toJSONString(producerMqMessage));
                        sysRocketmqDedup.setStatus(1);

                        transMqProducer.send(producerMqMessage);
                        log.info("mq成功记录【{}】", producerMqMessage);
                    }
                    log.info("当前mpc交易key 【{}】", transactionParam.getTxKey());

                }

                webHookResponse.setMessage("SUCCESS");
                webHookResponse.setCode("200");
                comMpcWebHook.setResp(JSONObject.toJSONString(webHookResponse));
                comMpcWebHookDao.updateById(comMpcWebHook);
            }

        }catch (Exception e) {
            log.error("执行失败【{}】", e.getMessage());
            throw new RuntimeException(e);
        }

        return webHookResponse;
    }
}
